// #include <iostream>
// #include <vector>
// #include <list>
// #include <string>
// #include <cassert>
// #include <cstring>
// using namespace std;
// namespace lnb
// {
// 	class string
// 	{
// 	public:
// 		typedef char* iterator;
// 		typedef const char* const_iterator;
// 		iterator begin()
// 		{
// 			return _arr;
// 		}
// 		iterator end()
// 		{
// 			return _arr + _size;
// 		}

// 		const iterator begin()const
// 		{
// 			return _arr;
// 		}
// 		const iterator end()const
// 		{
// 			return _arr + _size;
// 		}



// 		string(const char* str = "")
// 			:_size(strlen(str))
// 			, _capacity(_size)
// 		{
// 			cout << "string(const char* str)" << endl;
// 			if (_size == 0)
// 			{
// 				_capacity = 4;
// 			}
// 			_arr = new char[_capacity+1];
// 			strcpy(_arr, str);
// 		}


// 		string(const string& str)
// 		{
// 			cout << "string(const string& str)——深拷贝" << endl;
// 			_arr = new char[str._capacity + 1];
// 			strcpy(_arr, str._arr);
// 			_size = str._size;
// 			_capacity = str._capacity;
// 		}

// 		string(string&& str)
// 			:_arr(nullptr),
// 			_size(0),
// 			_capacity(0)
// 		{
// 			cout << "string(const string&& str)——移动拷贝" << endl;
// 			swap(str);//这边之所以可以传递到左值引用，是因为当实参传给str后，有了左值的属性
// 		}
		

// 		const string& operator=(const string& str)
// 		{
// 			cout << "const string& operator=(const string& str)—赋值重载" << endl;
// 			if (this != &str)
// 			{
// 				char* tmp = new char[str._capacity + 1];
// 				delete[] _arr;
// 				_arr = tmp;
// 				strcpy(_arr, str._arr);
// 				_capacity = str._capacity;
// 				_size = str._size;
// 			}
// 			return  *this;
// 		}

// 		const string& operator=(string&& str)
// 		{
// 			cout << "const string& operator=(string&& str)——移动赋值" << endl;
// 			swap(str);
// 			return *this;
// 		}



// 		~string()
// 		{
// 			delete[] _arr;
// 			_size = _capacity = 0;
// 		}



// 		const char* c_str(void)
// 		{
// 			return _arr;
// 		}

// 		size_t size()const
// 		{
// 			return _size;
// 		}
// 		size_t capacity()const
// 		{
// 			return _capacity;
// 		}


// 		char& operator[](size_t pos)
// 		{
// 			assert(pos < _size);
// 			return _arr[pos];
// 		}

// 		char& operator[](size_t pos)const
// 		{
// 			assert(pos < _size);
// 			return _arr[pos];
// 		}


	

// 		void Print(const string& str)
// 		{
// 			for (size_t i = 0; i < str._size; i++)
// 			{
// 				cout << str[i] << " ";
// 			}
// 			cout << endl;

// 			iterator bg = str.begin();
// 			while (bg != str.end())
// 			{
// 				cout << *bg << endl;
// 				bg++;
// 			}

// 		}


// 		void reserve(size_t size)
// 		{
// 			char* tmp = new char[size + 1];
// 			strcpy(tmp, _arr);
// 			delete _arr;
// 			_arr = tmp;
// 			_capacity = size;
// 		}




// 		void resize(size_t size, char c = '\0')
// 		{
// 			if (size <= _size)
// 			{
// 				_arr[size] = '\0';
// 				_size = size;
// 			}
// 			else
// 			{
// 				if (size > _capacity)
// 				{
// 					reserve(size);
// 				}
// 				size_t i = _size;
// 				while (i < size)
// 				{
// 					_arr[i] = c;
// 					i++;
// 				}
// 				_size = size;
// 				_arr[_size] = '\0';
// 			}
// 		}
// 		void swap(string& str)
// 		{
// 			std::swap(_arr, str._arr);
// 			std::swap(_size, str._size);
// 			std::swap(_capacity, str._capacity);
// 		}
// 	private:
// 		char* _arr;
// 		size_t _size;
// 		size_t _capacity;
// 		static const size_t npos = -1;
// 	};
// }

// class Date
// {
// public:
// 	Date(int year,int month,int day)
// 		:_year(year),
// 		_month(month),
// 		_day(day)
// 	{
// 		cout << "Date(int year,int month,int day)" << endl;
// 	}

// 	Date(Date&& d)
// 	{

// 		cout << "Date(Date&& d)——移动拷贝" << endl;
// 	}


// 	Date(const Date& d)
// 	{
// 		cout << "Date(const Date& d)——拷贝构造函数" << endl;
// 	}



// private:
// 	int _year;
// 	int _month;
// 	int _day;
// };
// int main()
// {
// 	/*list<lnb::string> mylist;
// 	mylist.push_back("1111");
// 	cout << "----------------------" << endl;
// 	mylist.emplace_back("1111");*/

// 	/*list<Date> mylist;
// 	mylist.push_back({ 2024,11,18 });
// 	cout << "----------------------" << endl;
// 	mylist.emplace_back( 2024,11,18);*/

// 	lnb::string str("hello world");
// 	vector<Date> myvector;
// 	myvector.push_back({2024,5,28});
// 	cout << "----------------------" << endl;
// 	myvector.emplace_back(2024,5,29);
// 	return 0;
// }

#include <iostream>
#include <thread>
#include <condition_variable>
#include <stack>
#include <mutex>
#include <cstdlib>
#include <ctime>
#include <unistd.h>
using namespace std;
condition_variable cv_productor;//定义个条件变量,生产者的
condition_variable cv_customer;//定义个条件变量,消费者的
stack<int> container;//存放数据的容器
mutex mtx;
#define SIZE 5
void Productor()
{
	while (1)
	{
		unique_lock<mutex> ck(mtx);
		while (container.size() == SIZE)//如果满足这个条件，线程就会挂起等待
		{
			cv_productor.wait(ck);//挂起后等待唤醒
		}
		container.push(rand() % 100 + 1);
		cv_customer.notify_one();//唤醒消费者一个线程
		sleep(1);
	}
}
void Customer()
{
	while (1)
	{
		unique_lock<mutex> ck(mtx);
		while (container.empty())
		{
			cv_customer.wait(ck);
		}
		int ret = container.top();
		container.pop();
		cout << ret << endl;
		fflush(stdout);
		cv_productor.notify_one();//唤醒生产者其中一个线程
		//sleep(1);//让消费者慢一点
	}
}

int main()
{
	srand((unsigned)time(nullptr));
	thread thread_array_productor[SIZE];
	for (int i = 0; i < SIZE; i++)//生产者
	{
		thread_array_productor[i] = thread(Productor);//创建线程并启动
	}

	thread thread_array_customer[SIZE];
	for (int i = 0; i < SIZE; i++)//消费者
	{
		thread_array_customer[i] = thread(Customer);//创建线程并启动
	}
	


	//主线程等待回收线程
	for (auto& e : thread_array_productor)
	{
		e.join();
	}

	for (auto& e : thread_array_customer)
	{
		e.join();
	}

	return 0;
}